/*
@title: Order the kitchen!
@description: "Order the Kitchen!" is an endless management game where you run a restaurant and must organize incoming dishes by placing them next to others of their kind. Your goal is to see how long you can last by strategically arranging the dishes as rounds progress. The game challenges your organization skills under time pressure in a bustling restaurant setting.
@author: mrdarip
@tags: ['endless']
@addedOn: 2024-06-29
👨‍🍳 DESCRIPTION:
You are running a restaurant, so you must keep it ordered, as you recive dishes,
you must put them beside others of their kind, let's see how long you last!

🎮 CONTROLS:
a/d: move
l: interact
k: reset

*/

const player = "i";

const empty = "e";

const plate = "p";
const fork = "f";
const mug = "m";
const knife = "k";

const bg0 = "0";
const bg1 = "1";
const bg2 = "2";
const bg3 = "3";
const bg4 = "4";
const bg5 = "5";
const bg6 = "6";
const bg7 = "7";

const bg8 = "8";
const bg9 = "9";
const bga = "a";
const bgb = "b";
const bgc = "c";
const bgd = "d";
const bge = "g";
const bgf = "h";

let bgIndex = 0;
let bg;

setLegend(
  [
    player,
    bitmap`
................
.......00.......
.......00.......
......0200......
......0200......
.....020000.....
.....020000.....
....02000000....
....02000000....
...0000000000...
...0000000000...
.......00.......
.......00.......
.......00.......
.......00.......
................`,
  ],
  [
    plate,
    bitmap`
....22222222....
...2222222222...
..222111111222..
.22112222221122.
2221222222221222
2212222222222122
2212222222222122
2212222222222122
2212222222222122
2212222222222122
2212222222222122
2221222222221222
.22112222221122.
..222111111222..
...2222222222...
....22222222....`,
  ],
  [
    fork,
    bitmap`
...LL..LL..LL...
...LL..LL..LL...
...LL..LL..LL...
...LL..LL..LL...
...LL..LL..LL...
...LLLLLLLLLL...
...LLLLLLLLLL...
.......LL.......
.......LL.......
.......LL.......
.......LL.......
.......LL.......
.......LL.......
.......LL.......
.......LL.......
.......LL.......`,
  ],
  [
    mug,
    bitmap`
................
................
.55555555555....
.55555555555....
.55555555555555.
.556565556555555
.56666656655..55
.55656555655..55
.56666655655..55
.55656556665..55
.555555555555555
.55555555555555.
.55555555555....
.55555555555....
................
................`,
  ],
  [
    knife,
    bitmap`
......1.........
......11........
......111.......
......1111......
......1111......
......1111......
......1111......
......1111......
......1111......
......1111......
......1111......
......00........
......00........
......00........
......00........
......00........`,
  ],
  [
    empty,
    bitmap`
11.111.11.111.11
1..............1
................
1..............1
1..............1
1..............1
................
1..............1
1..............1
................
1..............1
1..............1
1..............1
................
1..............1
11.111.11.111.11`,
  ],
  [
    bg0,
    bitmap`
2222222277777777
2222222277777777
2222222277777777
2222222277777777
2222222277777777
2222222277777777
2222222277777777
2222222277777777
7777777722222222
7777777722222222
7777777722222222
7777777722222222
7777777722222222
7777777722222222
7777777722222222
7777777722222222`,
  ],
  [
    bg1,
    bitmap`
2777777772222222
7222222227777777
7222222227777777
7222222227777777
7222222227777777
7222222227777777
7222222227777777
7222222227777777
7222222227777777
2777777772222222
2777777772222222
2777777772222222
2777777772222222
2777777772222222
2777777772222222
2777777772222222`,
  ],
  [
    bg2,
    bitmap`
2277777777222222
2277777777222222
7722222222777777
7722222222777777
7722222222777777
7722222222777777
7722222222777777
7722222222777777
7722222222777777
7722222222777777
2277777777222222
2277777777222222
2277777777222222
2277777777222222
2277777777222222
2277777777222222`,
  ],
  [
    bg3,
    bitmap`
2227777777722222
2227777777722222
2227777777722222
7772222222277777
7772222222277777
7772222222277777
7772222222277777
7772222222277777
7772222222277777
7772222222277777
7772222222277777
2227777777722222
2227777777722222
2227777777722222
2227777777722222
2227777777722222`,
  ],
  [
    bg4,
    bitmap`
2222777777772222
2222777777772222
2222777777772222
2222777777772222
7777222222227777
7777222222227777
7777222222227777
7777222222227777
7777222222227777
7777222222227777
7777222222227777
7777222222227777
2222777777772222
2222777777772222
2222777777772222
2222777777772222`,
  ],
  [
    bg5,
    bitmap`
2222277777777222
2222277777777222
2222277777777222
2222277777777222
2222277777777222
7777722222222777
7777722222222777
7777722222222777
7777722222222777
7777722222222777
7777722222222777
7777722222222777
7777722222222777
2222277777777222
2222277777777222
2222277777777222`,
  ],
  [
    bg6,
    bitmap`
2222227777777722
2222227777777722
2222227777777722
2222227777777722
2222227777777722
2222227777777722
7777772222222277
7777772222222277
7777772222222277
7777772222222277
7777772222222277
7777772222222277
7777772222222277
7777772222222277
2222227777777722
2222227777777722`,
  ],
  [
    bg7,
    bitmap`
2222222777777772
2222222777777772
2222222777777772
2222222777777772
2222222777777772
2222222777777772
2222222777777772
7777777222222227
7777777222222227
7777777222222227
7777777222222227
7777777222222227
7777777222222227
7777777222222227
7777777222222227
2222222777777772`,
  ],
  [
    bg8,
    bitmap`
2222222233333333
2222222233333333
2222222233333333
2222222233333333
2222222233333333
2222222233333333
2222222233333333
2222222233333333
3333333322222222
3333333322222222
3333333322222222
3333333322222222
3333333322222222
3333333322222222
3333333322222222
3333333322222222`,
  ],
  [
    bg9,
    bitmap`
2333333332222222
3222222223333333
3222222223333333
3222222223333333
3222222223333333
3222222223333333
3222222223333333
3222222223333333
3222222223333333
2333333332222222
2333333332222222
2333333332222222
2333333332222222
2333333332222222
2333333332222222
2333333332222222`,
  ],
  [
    bga,
    bitmap`
2233333333222222
2233333333222222
3322222222333333
3322222222333333
3322222222333333
3322222222333333
3322222222333333
3322222222333333
3322222222333333
3322222222333333
2233333333222222
2233333333222222
2233333333222222
2233333333222222
2233333333222222
2233333333222222`,
  ],
  [
    bgb,
    bitmap`
2223333333322222
2223333333322222
2223333333322222
3332222222233333
3332222222233333
3332222222233333
3332222222233333
3332222222233333
3332222222233333
3332222222233333
3332222222233333
2223333333322222
2223333333322222
2223333333322222
2223333333322222
2223333333322222`,
  ],
  [
    bgc,
    bitmap`
2222333333332222
2222333333332222
2222333333332222
2222333333332222
3333222222223333
3333222222223333
3333222222223333
3333222222223333
3333222222223333
3333222222223333
3333222222223333
3333222222223333
2222333333332222
2222333333332222
2222333333332222
2222333333332222`,
  ],
  [
    bgd,
    bitmap`
2222233333333222
2222233333333222
2222233333333222
2222233333333222
2222233333333222
3333322222222333
3333322222222333
3333322222222333
3333322222222333
3333322222222333
3333322222222333
3333322222222333
3333322222222333
2222233333333222
2222233333333222
2222233333333222`,
  ],
  [
    bge,
    bitmap`
2222223333333322
2222223333333322
2222223333333322
2222223333333322
2222223333333322
2222223333333322
3333332222222233
3333332222222233
3333332222222233
3333332222222233
3333332222222233
3333332222222233
3333332222222233
3333332222222233
2222223333333322
2222223333333322`,
  ],
  [
    bgf,
    bitmap`
2222222333333332
2222222333333332
2222222333333332
2222222333333332
2222222333333332
2222222333333332
2222222333333332
3333333222222223
3333333222222223
3333333222222223
3333333222222223
3333333222222223
3333333222222223
3333333222222223
3333333222222223
2222222333333332`,
  ]
);

let level = 0;
const levels = [
  map`
..........
pp.ffkk.mm
i.........
..........
..e.....e.
..........
..........
..........`,
  map`
..........
.k.k..k.k.
..........
..........
..........
..........
.f.f..f.f.
..........`,
];

const mainTune = tune`
225.5639097744361: E4^225.5639097744361 + G5/225.5639097744361 + D4~225.5639097744361,
225.5639097744361: F4^225.5639097744361,
225.5639097744361: G4^225.5639097744361 + E5^225.5639097744361,
225.5639097744361: F5^225.5639097744361,
225.5639097744361: G5^225.5639097744361 + E4^225.5639097744361 + C4~225.5639097744361,
225.5639097744361,
225.5639097744361: E4^225.5639097744361 + E5^225.5639097744361,
225.5639097744361: F4^225.5639097744361,
225.5639097744361: G4^225.5639097744361 + E5^225.5639097744361 + D4~225.5639097744361,
225.5639097744361: F5^225.5639097744361,
225.5639097744361: G5^225.5639097744361 + E4^225.5639097744361,
225.5639097744361,
225.5639097744361: E4^225.5639097744361 + E5^225.5639097744361 + C4~225.5639097744361,
225.5639097744361: F4^225.5639097744361,
225.5639097744361: G4^225.5639097744361 + E5^225.5639097744361,
225.5639097744361: A4^225.5639097744361 + F5^225.5639097744361,
225.5639097744361: B4^225.5639097744361 + G5^225.5639097744361 + D4~225.5639097744361,
225.5639097744361: A4^225.5639097744361 + A5^225.5639097744361,
225.5639097744361: B5^225.5639097744361 + F4^225.5639097744361 + F5/225.5639097744361,
225.5639097744361: A5^225.5639097744361 + G4^225.5639097744361,
225.5639097744361: F4^225.5639097744361 + F5^225.5639097744361 + C4~225.5639097744361,
225.5639097744361: G5^225.5639097744361 + E4^225.5639097744361 + D5/225.5639097744361,
225.5639097744361: F5^225.5639097744361 + F4^225.5639097744361,
225.5639097744361: E5^225.5639097744361 + F5/225.5639097744361 + E4^225.5639097744361,
225.5639097744361: C4~225.5639097744361 + F5^225.5639097744361 + D4^225.5639097744361,
225.5639097744361: E5^225.5639097744361 + D5/225.5639097744361 + E4/225.5639097744361,
225.5639097744361: D5^225.5639097744361,
225.5639097744361: G4/225.5639097744361,
225.5639097744361: C4~225.5639097744361 + F5/225.5639097744361,
225.5639097744361: E4/225.5639097744361,
225.5639097744361: D5/225.5639097744361,
225.5639097744361: G4/225.5639097744361`;
const gameOverTune = tune`
500: E4~500 + G5^500 + D4/500,
500: F4~500,
500: G4~500 + E5~500,
500: F5~500,
500: C4/500 + G5~500 + E4~500,
500,
500: E4~500 + E5~500,
500: F4~500,
500: G4~500 + E5~500 + D4/500,
500: F5~500,
500: G5~500 + E4~500,
500,
500: C4/500 + E4~500 + E5~500,
500: F4~500,
500: G4~500 + E5~500,
500: A4~500 + F5~500,
500: B4~500 + G5~500 + D4/500,
500: A4~500 + A5~500,
500: B5~500 + F4~500 + F5^500,
500: A5~500 + G4~500,
500: C4/500 + F4~500 + F5~500,
500: G5~500 + E4~500 + D5^500,
500: F5~500 + F4~500,
500: E5~500 + F5^500 + E4~500,
500: C4/500 + F5~500 + D4~500,
500: E5~500 + D5^500 + E4^500,
500: D5~500,
500: G4^500,
500: C4/500 + F5^500,
500: E4^500,
500: D5^500,
500: G4^500`;

let playback = playTune(mainTune, Infinity);

let items = [plate, fork, mug, knife];
let stored;

let addingObjectTurn;
let puttingItem;
let itemToReturn;

let points;
let highscore = 0;
resetGame()


onInput("a", () => {
  getFirst(player).x -= 1;
});

onInput("d", () => {
  getFirst(player).x += 1;
});

onInput("l", () => {
  playerX = getFirst(player).x;
  itemOverPlayer = getTile(playerX, 1)[0];

  if (addingObjectTurn) {
    if (typeof itemOverPlayer == "undefined") {
      passTurn();

      addSprite(playerX, 1, puttingItem);
      storeItem(puttingItem, 1);

      puttingItem = items[getRandomInt(items.length)];

      updateItemToPut(empty);
      itemToReturn = getItemToGive();

      checkScreenIsValid();
    }
  } else {
    if (
      typeof itemOverPlayer != "undefined" &&
      itemToReturn == itemOverPlayer.type
    ) {
      passTurn();

      storeItem(itemOverPlayer.type, -1);
      itemOverPlayer.remove();

      updateItemToPut(puttingItem);
      updateItemToGive(empty);
    }
  }
});

onInput("k", () => {
  resetGame();
});

afterInput(() => {});

var bgLoop = setInterval(() => {
  bgIndex++;
  setBackground(bg[bgIndex % bg.length]);
}, 100);

function resetGame() {
  goToScene(0, mainTune, [bg0, bg1, bg2, bg3, bg4, bg5, bg6, bg7]);

  points = 0;
  displayPoints();
  displayHighScore();

  addText("put", {
    x: 1,
    y: 9,
    color: color`0`,
  });
  addText("give", {
    x: 12,
    y: 9,
    color: color`0`,
  });

  stored = [2, 2, 2, 2];
  addingObjectTurn = false;
  puttingItem = items[getRandomInt(items.length)];
  itemToReturn = getItemToGive();
}

function getRandomInt(max) {
  return Math.floor(Math.random() * max);
}

function getItemToGive() {
  item = getItemFromScreen();
  updateItemToGive(item);

  return item;
}

function getItemFromScreen() {
  let itemsOnScreen = stored.reduce((a, b) => a + b, 0);
  randomCount = getRandomInt(itemsOnScreen);
  returnIndex = -1;
  sum = 0;
  do {
    returnIndex++;
    sum += stored[returnIndex];
  } while (sum <= randomCount);

  return items[returnIndex];
}

function storeItem(item, quantity) {
  stored[items.indexOf(item)] += quantity;
}

function displayPoints(x = 1, y = 12) {
  addText("points: " + points, {
    x: x,
    y: y,
    color: color`0`,
  });

  if (points > highscore) {
    highscore = points
    displayHighScore()
  }
}

function displayHighScore(x = 1, y = 14) {
  addText("highscore: " + highscore, {
    x: x,
    y: y,
    color: color`0`,
  });
}

function passTurn() {
  addingObjectTurn = !addingObjectTurn;
  points++;
  displayPoints();
}

function updateItemToPut(newItem) {
  updateItemAt(2, 4, newItem);
}

function updateItemToGive(newItem) {
  updateItemAt(8, 4, newItem);
}

function updateItemAt(x, y, newItem) {
  clearTile(x, y);
  addSprite(x, y, newItem);
}

function checkScreenIsValid() {
  let registered = [];
  for (let i = 0; i < width(); i++) {
    let item = getTile(i, 1)[0];
    if (typeof item != "undefined") {
      if (
        !registered.includes(item.type) ||
        registered[registered.length - 1] == item.type
      ) {
        registered.push(item.type);
      } else {
        goToScene(1, gameOverTune, [bg8, bg9, bga, bgb, bgc, bgd, bge, bgf]);
        addText("game\nover", {
          x: 8,
          y: 7,
          color: color`0`,
        });

        displayHighScore(2, 15)
        displayPoints(2, 14)

      }
    }
  }
}

function goToScene(scene, bgTune, bgTiles) {
  playback.end();
  playback = playTune(bgTune, Infinity);

  clearText();

  bg = bgTiles;

  level = scene;
  setMap(levels[level]);
}